-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Store a MirSource inside every Body
#77430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
b933634 to
8bc9f3d
Compare
|
@lcnr I don't understand how to use |
8bc9f3d to
3510421
Compare
|
r? @lcnr I guess. I was expecting this to be a straightforward refactoring, but #74113 has made me a bit frustrated It feels like we could make |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So WithOptConstParam is used if we ever call type_of for the mir body.
As we call type_of in some annoyingly annoying places, we have to somehow get the DefId of the relevant const param there.
Once we build a Body with the correct WithOptConstParam, we should then be able to use that mir_source in the remaining mir_* queries.
WithOptConstParam infects all of the mir queries as we call optimized_mir during typeck (which is where the cycle errors are the problem) so we have to somehome thread these calls down to mir_built which uses type_of. Not sure if type_of is called in some other mir queries
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def_id: DefId, | |
| def: ty::WithOptConstParam<DefId>, |
I think it should be easier to already pass the correct WithOptConstParam into this builder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the part I'm not understanding. What are the invariants of WithOptConstParam? When is it okay to be unknown? Do I have to call try_upgrade manually?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The invariant of WithOptConstParam is that if self.const_param_did.is_some(), then self.const_param_did == tcx.opt_const_param_of(self.did). To prevent cycle errors self.const_param_did should also be Some if it is used during typeck, did is a const argument and we want to know tcx.type_of(did), which we then replace with tcx.type_of(def.def_id_for_type_of()).
You should never have to call try_upgrade except at the start of a query taking ty::WithOptConstParam so that we only evaluate it once.
It is okay to use unknown if we are either done with typeck or tcx.opt_const_param_of(self.did) would/did return None.
Looks like it might be worth it to add a section to the rustc-dev-guide about WithOptConstParam 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it might be worth it to add a section to the rustc-dev-guide about WithOptConstParam thinking
As I've alluded to, I think time would be better spent better encapsulating this system. I don't particularly want to think about it when writing MIR transformations. I realize I'm being a bit curmudgeonly here and that this is in service of a feature which I'm super excited about (thanks BTW!), but technical debt is a real concern, especially in mir-opt land.
Is there anything we could do to reduce the surface area here? We can discuss this in a separate issue I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I didn't send the message I wanted to send here 😅
While working on this I experimented with some different approaches and the less invasive ones all ended up being unsound in the face of incremental compilation. So I would be glad - and a bit annoyed 😆 - if you are able to come up with a less invasive solution here, but do think that this will be quite hard to do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some ideas, but if you've already explored alternatives, it's unlikely that I'll be able to do better. I've not given up quite yet though 😄.
compiler/rustc_middle/src/mir/mod.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| pub fn item(def_id: DefId) -> Self { | |
| pub fn item(def: ty::WithOptParam<DefId>) -> Self { |
my personal preference, makes it harder to get this wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't mine. I've just moved it from transform/mod.rs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I still think that this would be a good change though 🤔 you don't have to do this in this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| add_moves_for_packed_drops(tcx, body, body.source.def_id()); | |
| add_moves_for_packed_drops(tcx, body); |
we only use to body source in add_moves_for_packed_drops, don't we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| def_id: body.source.def_id().expect_local(), |
Can we instead use the body def_id here?
|
☔ The latest upstream changes (presumably #77396) made this pull request unmergeable. Please resolve the merge conflicts. Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels: |
|
There's a follow-up to #77427, which is to remove the |
920fa8f to
ef49daa
Compare
| tcx.alloc_steal_mir(mir_build(tcx, def)) | ||
| let mut body = mir_build(tcx, def); | ||
| if def.const_param_did.is_some() { | ||
| assert!(matches!(body.source.instance, ty::InstanceDef::Item(_))); | ||
| body.source = MirSource::from_instance(ty::InstanceDef::Item(def.to_global())); | ||
| } | ||
|
|
||
| tcx.alloc_steal_mir(body) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lcnr what should this look like in your eyes? It seems like we should do this when the MIR is built instead, but that means calling try_upgrade outside of a query?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let body = mir_built(txc, def);
tcx.alloc_steal_mir(body)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have def as an input to mir_built, so we should be able to use the correct source right from the start here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That causes cycle errors during type-checking.
edit: Sorry, I see my force-push erased the run results for the version of this PR without this commit. I'll try to find the failing test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you think that we should call try_upgrade here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant inside rustc_mir_builder::Builder::build() or so.
yeah, we should never have to call try_upgrade inside of mir_built after the initial call at the start of the query. If you can get the failing state again I would gladly look into what's going wrong there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error[E0391]: cycle detected when type-checking `main`
--> /home/mackendy/src/rust/rust/alt/src/test/ui/const-generics/slice-const-param-mismatch.rs:18:33
|
LL | let _: ConstBytes<b"AAA"> = ConstBytes::<{&[0x41, 0x41, 0x41]}>;
| ^^^^^^^^^^^^^
|
note: ...which requires simplifying constant for the type system `main::{constant#9}`...
--> /home/mackendy/src/rust/rust/alt/src/test/ui/const-generics/slice-const-param-mismatch.rs:18:46
|
LL | let _: ConstBytes<b"AAA"> = ConstBytes::<{&[0x41, 0x41, 0x41]}>;
| ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `main::{constant#9}`...
--> /home/mackendy/src/rust/rust/alt/src/test/ui/const-generics/slice-const-param-mismatch.rs:18:46
|
LL | let _: ConstBytes<b"AAA"> = ConstBytes::<{&[0x41, 0x41, 0x41]}>;
| ^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires normalizing `main::{constant#9}::promoted[0]`...
note: ...which requires resolving instance `main::{constant#9}`...
--> /home/mackendy/src/rust/rust/alt/src/test/ui/const-generics/slice-const-param-mismatch.rs:18:46
|
LL | let _: ConstBytes<b"AAA"> = ConstBytes::<{&[0x41, 0x41, 0x41]}>;
| ^^^^^^^^^^^^^^^^^^^^^
note: ...which requires computing the optional const parameter of `main::{constant#9}`...
--> /home/mackendy/src/rust/rust/alt/src/test/ui/const-generics/slice-const-param-mismatch.rs:18:46
|
LL | let _: ConstBytes<b"AAA"> = ConstBytes::<{&[0x41, 0x41, 0x41]}>;
| ^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires type-checking `main`, completing the cycle
= note: cycle used when type-checking all item bodies
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0308, E0391.
For more information about an error, try `rustc --explain E0308`.
------------------------------------------
failures:
[ui] ui/const-generics/slice-const-param-mismatch.rs#full
[ui] ui/const-generics/slice-const-param.rs#full
Cycle along with the two failing tests. This is what happens with just the first commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
= note: ...which requires normalizing `main::{constant#9}::promoted[0]`...
Is probably where this goes wrong, so we somehow are not using the full def for promoteds.
Not at home rn, will look at where exactly this goes wrong tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So your solution is probably the easiest for now...
The actual mir builder currently only uses a DefId and has quite a few entry points.
After we merge this I am going to look into a good way to start with the correct WithOptConstParam in the build::Builder.
The way I expect to do this is a bit like the following but without using WithOptConstParam::unknown there, which is a bit more invasive than I would like in this PR: lcnr@9061538
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from this I think this is mostly ready for merge 🤔 is there still something you want to do in that PR?
There's a cleaner way of doing this, but it involves passing `WithOptConstParam` around in more places. We're going to try to explore different approaches before committing to that.
187acab to
606655e
Compare
|
yeah, let's fix the remaining nits in followup PRs @bors r+ |
|
📌 Commit 606655e has been approved by |
|
☀️ Test successful - checks-actions, checks-azure |
|
This PR introduced an ICE for mir-opt-level 2 and above: #77564. |
| // FIXME: Give a bonus to functions with only a single caller | ||
|
|
||
| let param_env = tcx.param_env(self.source.def_id()); | ||
| let param_env = tcx.param_env(callee_body.source.def_id()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ecstatic-morse this is the wrong source, will open a PR for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opened #77568
Replace `(Body, DefId)` with `Body` where possible Follow-up to rust-lang#77430. I `grep`-ed for parameter lists in which a `Body` appeared within a few lines of a `DefId`, so it's possible that I missed some cases, but this should be pretty complete. Most of these changes were mechanical, but there's a few places where I started calling things "caller" and "callee" when multiple `DefId`s were in-scope at once. Also, we should probably have a helper function on `Body` that returns a `LocalDefId`. I can do that in this PR or in a follow-up.
…morse inliner: use caller param_env We used the callee param env instead of the caller param env by accident in rust-lang#77430, this PR fixes that and caches it in the `Inliner` struct. fixes rust-lang#77564 r? @ecstatic-morse
Resolves #77427.
r? @ghost